package org.stvd.service.admin.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.stvd.core.dto.QueryResult;
import org.stvd.core.util.StringUtil;
import org.stvd.entities.admin.Department;
import org.stvd.entities.admin.UserDep;
import org.stvd.repository.admin.DepartmentDao;
import org.stvd.repository.admin.RolesDao;
import org.stvd.repository.admin.UserDepDao;
import org.stvd.service.admin.DepartmentService;
import org.stvd.service.base.impl.BaseServiceImpl;

@Service("departmentService")
public class DepartmentServiceImpl extends BaseServiceImpl<Department> implements DepartmentService {

    @Resource(name = "DepartmentDao")
    private DepartmentDao departmentDao;
    @Resource(name = "UserDepDao")
    private UserDepDao userDepDao;
    @Resource(name = "RolesDao")
    private RolesDao rolesDao;

    @Override
    public List<Map<String, Object>> listUserDepByGuid(String guid) {
        return departmentDao.listUserDepByGuid(guid);
    }
    
    @Override
    public List<Department> findAllDepByGuid(String guid) {
        if(StringUtil.isEmpty(guid)) {
            return null;
        }
        return departmentDao.findAllDepByGuid(guid);
    }
    
    @Override
    public List<Department> getFormatAllDepByGuid(String guid) {
        List<Department> depList = findAllDepByGuid(guid);
        if (depList!=null) {
            for (Department dep : depList) {
                int level = getDepartmentLevel(depList, dep.getUpperId(), 1);
                String prefix = "";
                for(int i = 1; i < level; i++) {
                    prefix += "---- " ;
                }
                dep.setDepName(prefix + dep.getDepName());
            }
        }
        Collections.sort(depList, new Comparator<Department>(){  
            public int compare(Department d1, Department d2) {  
                String innerCode1 = d1.getInnerCode();  
                String innerCode2 = d2.getInnerCode();      
                return innerCode1.compareTo(innerCode2);    
            }  
        });
        return depList;
    }
    
    @Override
    public List<Department> getFormatChildDepartment(String depId, String guid) {
        List<Department> depList = departmentDao.getAllChildDepartment(depId, guid);
        if (depList!=null) {
            for (Department dep : depList) {
                int level = getDepartmentLevel(depList, dep.getUpperId(), 1);
                String prefix = "";
                for(int i = 1; i < level; i++) {
                    prefix += "---- " ;
                }
                dep.setDepName(prefix + dep.getDepName());
            }
        }
        Collections.sort(depList, new Comparator<Department>(){  
            public int compare(Department d1, Department d2) {  
                String innerCode1 = d1.getInnerCode();  
                String innerCode2 = d2.getInnerCode();      
                return innerCode1.compareTo(innerCode2);    
            }  
        });
        return depList;
    }
    
    @Override
    public Department getDepartmentByDepCode(String depCode, String guid) {
        if(StringUtil.isEmpty(depCode) || StringUtil.isEmpty(guid)) {
            return null;
        }
        return departmentDao.getDepartmentByDepCode(depCode, guid);
    }
    
    public int getDepartmentLevel(List<Department> depList, String upperId, int level) {
        for (Department department : depList) {
            if(department.getDepId().equals(upperId)) {
                level += 1;
                level = getDepartmentLevel(depList, department.getUpperId(), level);
                break;
            }
        }
        return level;
    }
    
    @Override
    public void insertUserDep(String userId, String depCode) {
        List<Map<String, Object>> list = departmentDao.listUserNoneDepGuid(userId, depCode);
        if(list!=null && list.size() > 0) {
            UserDep userDep = null;
            for (Map<String, Object> dataMap : list) {
                userDep = new UserDep();
                userDep.setId(StringUtil.getRandomUUID());
                userDep.setUserId(userId);
                userDep.setDepId((String)dataMap.get("dep_id"));
                userDep.setGuid((String)dataMap.get("guid"));
                userDepDao.insert(userDep);
                userDep = null;
            }
        }
    }
    
    @Override
    @Cacheable(value = "adminCache", key = "'DepartmentService.findImeDepartmentByJsm('+#jsm+','+#guid+')'")
    public List<Department> findImeDepartmentByJsm(String jsm, String guid) {
        return departmentDao.findImeDepartmentByJsm(jsm, guid);
    }

    @Override
    @Transactional
    public void insertUserDep(String userId, String depId, String guid) {
        departmentDao.insertUserDep(userId, depId, guid);
    }

    @Override
    public void insertUserDepMap(String userId, String depCode, String guid) {
        Department department = departmentDao.getDepartmentByDepCode(depCode, guid);
        if(department!=null) {
            UserDep userDep = userDepDao.getUserDepByDepCode(userId, depCode, guid);
            if(userDep==null) {
                userDep = new UserDep();
                userDep.setId(StringUtil.getRandomUUID());
            }
            userDep.setUserId(userId);
            userDep.setDepId(department.getDepId());
            userDep.setGuid(guid);
            userDepDao.update(userDep);
        }
    }

    @Override
    public void deleteUserDepMap(String userId, String depCode, String guid) {
        userDepDao.deleteUserDepMap(userId, depCode, guid);
    }
    
    @Override
    public List<Department> findDepByUid(String userId, String guid) {
        return departmentDao.findDepByUid(userId, guid);
    }

    @Override
    public QueryResult<Department> getDepartmentQueryResult(int start, int limit, String depName, String guid) {
        return departmentDao.getDepartmentQueryResult(start, limit, depName, guid);
    }

    @Override
    public List<Department> getChildDepartment(String depId, String guid) {
        return departmentDao.getChildDepartment(depId, guid);
    }

    public boolean isChildDepartment(String depId, String childDepId, String guid) {
        boolean bResult = false;
        List<Department> list = departmentDao.getAllChildDepartment(depId, guid);
        for (Department department : list) {
            if (department.getDepId().equals(childDepId)) {
                bResult = true;
            }
        }
        return bResult;
    }

    @Override
    @Transactional
    public void deleteDepartment(String depId, String guid) throws Exception {
        if (departmentDao.getChildDepartment(depId, guid).size() > 0) {
            throw new Exception("存在下级机构！");
        } else if (userDepDao.findUserDepByDepid(depId, guid).size() > 0) {
            throw new Exception("存在使用的用户！");
        } else if (rolesDao.findRolesByDepId(depId, guid).size() > 0) {
            throw new Exception("存在使用的角色！");
        } else {
            departmentDao.delete(Department.class, (String) depId);
        }
    }

    @Override
    public List<String> getParentDepids(Department department) {
        List<String> list = new ArrayList<String>();
        Department parentDep = departmentDao.findByPk(Department.class, department.getUpperId());
        if (parentDep != null) {
            list.add(parentDep.getDepId());
            list.addAll(getParentDepids(parentDep));
        }
        return list;
    }

    @Override
    public List<Department> getAllChildDepartment(String depId, String guid) {
        return departmentDao.getAllChildDepartment(depId, guid);
    }

    @Override
    public List<Department> findDepartmentByInnerCode(String innerCode, String guid) {
        return departmentDao.findDepartmentByInnerCode(innerCode, guid);
    }
}
